﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Entidades;
using LogicaNegocio;
using AccesoBD;
using Reportes;

namespace PresentacionEscritorio
{
    public partial class frmCobroAtencionMédica : Form, IFormsPadre_Hijo
    {
        private frmGestionTurnos2 formGestionTurno;
        private frmRegistrarLlegadaTurno formRegLlegadaTurno;

        private Recibo reciboNuevo;

        //datos que necesito para el cobro
        public long idTurno { get; set; }
        public Turno miTurno { get; set; }
        public long nroHCpaciente { get; set; }
      

        //objeto cobro a guardar en la bd
        private bool tieneConsultaAcobrar;
        List<DetalleRecibo> listaDetalles;
        private List<ObraSocialXPaciente> osPacientes;
        private Afiliacion planAfPaciente;
        private ObraSocial osPacienteSeleccionada;

        //variables del recibo
        private float subtotal;
        private float descuento;
        private float recargo;
        private float total;
        private string totalEnLetras;

        private float precioMedico;

        private PrecioACobrar precioRecibo;

        enum PrecioACobrar
        {
            particular,
            obraSocial,
            afiliado
        }

        public void SetFormGestionTurno(frmGestionTurnos2 frmGT)
        {
            formGestionTurno = frmGT;
        }

        public frmCobroAtencionMédica()
        {
            InitializeComponent();
        }

        private void frmCobroAtencionMédica_Load(object sender, EventArgs e)
        {
            listaDetalles = new List<DetalleRecibo>();

            timer2.Start();
            btnImprimir.Visible = false;

            //deshabilitamos los campos para que no sean modificables
            txtFechaHoraActual.ReadOnly = true;
            txtNroHC.Enabled = false;
            txtApellidoNombre.Enabled = false;
            txtDocumento.Enabled = false;

            lblNroAfiliado.Visible = false;
            lblOS.Visible = false;
            lblNroAfiliadoOS.Visible = false;
            lblTipoPlan.Visible = false;
            txtPlanAfiliacion.Visible = false;
            txtNroAfiliado.Visible = false;
            cmbOSpaciente.Visible = false;
            txtNroAfiliadoOS.Visible = false;

            //deshabilitar por defecto los descuentos y los recargos
            txtRecargo.Enabled = false;
            txtDescuento.Enabled = false;

            cargarComboEspecialidades();
            cargarComboPracticas();

            //obtenemos el turno
            miTurno = GestorAgendaTurnos.obtenerTurnoPorID(idTurno);
            miTurno = GestorAgendaTurnos.obtenerPacienteTurno(miTurno);

            //cargamos al paciente en el form
            cargarPaciente();

            validarEstadoTurno();

            //desahabilitamos el panel de cobro hasta que se seleccione el tipo de paciente para saber que precio hay que cobrar
            panelDetalleCobro.Enabled = false;
        }

        private void validarEstadoTurno()
        {
            if (miTurno.IdEstadoTurno == 3 || miTurno.IdEstadoTurno == 5)
            {
                tieneConsultaAcobrar = true;
                cargarConsulta();
            }
            else
                tieneConsultaAcobrar = false;
        }

        private void cargarComboEspecialidades()
        {
            cmbEspecialidades.DataSource = GestorEspecialidades.obtenerTodasEspecialidades();
            cmbEspecialidades.DisplayMember = "Nombre";
            cmbEspecialidades.ValueMember = "CodEspecialidad";
            cmbEspecialidades.SelectedIndex = -1;

            cmbEspecialidades.Enabled = false;
        }

        private void cargarComboPracticas()
        {
            cmbPracticas.DataSource = GestorPracticas.obtenerTodasPracticas();
            cmbPracticas.DisplayMember = "nombre";
            cmbPracticas.ValueMember = "codigo";
            cmbPracticas.SelectedIndex = -1;

            cmbPracticas.Enabled = false;
        }

        private void cargarPaciente()
        {
            txtNroHC.Text = miTurno.NroHCPaciente.ToString();
            txtApellidoNombre.Text = miTurno.NombrePaciente;

            //cargamos los otros datos
            Pacientess gestorPacientes = new Pacientess();
            Paciente pac = gestorPacientes.buscarPaciente(miTurno.NroHCPaciente);
            miTurno.Paciente = pac;
            txtDocumento.Text = "DNI " + pac.NroDocumento;

            cargarComboTipoPaciente();
        }

        private void cargarComboTipoPaciente()
        {
            cmbTipoPaciente.DataSource = GestorCobrosAtencionMedica.obtenerTodosTiposPaciente(miTurno.NroHCPaciente);
            cmbTipoPaciente.DisplayMember = "Nombre";
            cmbTipoPaciente.ValueMember = "IdTipoPaciente";
            cmbTipoPaciente.SelectedIndex = -1;
        }

        private void cargarConsulta()
        {
            //tieneConsultaAcobrar = true;

            int i = grdDetalleCobro.Rows.Add();
            grdDetalleCobro.Rows[i].Cells["Concepto"].Value = "Consulta médica " + miTurno.nombreEspecialidad;

            //falta cargar precio, que se hará recien cuando se seleccione la condición del paciente.
        }

        private void btnAgregarPractica_Click(object sender, EventArgs e)
        {

        }


        public void setFormPadre(Form formPadre)
        {
            if (formPadre.GetType() == typeof(frmGestionTurnos2))
                formGestionTurno = (frmGestionTurnos2)formPadre;
            else if (formPadre.GetType() == typeof(frmRegistrarLlegadaTurno))
                formRegLlegadaTurno = (frmRegistrarLlegadaTurno)formPadre;

        }

        public void setFormHijo(Form formHijo)
        {
            throw new NotImplementedException();
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            txtFechaHoraActual.Text = DateTime.Now.ToString();
        }

        private void cmbTipoPaciente_SelectionChangeCommitted(object sender, EventArgs e)
        {
            //cargar los precios segun el tipo de paciente que se selecciono, y el nro de afiliado u OS segun corresponda
            int idTipoPac = int.Parse(cmbTipoPaciente.SelectedValue.ToString());
            switch (idTipoPac)
            {
                case 1: //Particular
                    cargarPreciosParticular();
                    break;
                case 2: //Obra social
                    lblTipoPlan.Visible = false;
                    txtPlanAfiliacion.Visible = false;
                    lblNroAfiliado.Visible = false;
                    txtNroAfiliado.Visible = false;
                    lblOS.Visible = true;
                    cmbOSpaciente.Visible = true;
                    lblNroAfiliadoOS.Visible = true;
                    txtNroAfiliadoOS.Visible = true;

                    cargarOSpaciente();
                    break;
                case 3: //Afiliado
                    lblTipoPlan.Visible = true;
                    txtPlanAfiliacion.Visible = true;
                    lblNroAfiliado.Visible = true;
                    txtNroAfiliado.Visible = true;
                    lblOS.Visible = false;
                    cmbOSpaciente.Visible = false;
                    lblNroAfiliadoOS.Visible = false;
                    txtNroAfiliadoOS.Visible = false;

                    cargarPlanAfiliacionPaciente();
                    break;
                default:
                    break;
            }

            //ahora si habilitamos el panel de cobro
            panelDetalleCobro.Enabled = true;
        }

        private void cargarPreciosParticular()
        {
            //se usan los precios de lista de las especialidades y de las practicas
            precioRecibo = PrecioACobrar.particular;

            if (tieneConsultaAcobrar)
                cargarPrecioConsulta();

        }

        private void cargarPlanAfiliacionPaciente()
        {
            precioRecibo = PrecioACobrar.afiliado;
            if (planAfPaciente == null)
            {
                //traer afiliacion, plan de afiliacion y sus detalles
                planAfPaciente = GestorCobrosAtencionMedica.obtenerAfiliacionPaciente(miTurno.NroHCPaciente);
            }
            txtNroAfiliado.Text = planAfPaciente.nroAfiliado.ToString();
            txtPlanAfiliacion.Text = planAfPaciente.miPlanAfiliacion.nombre;

            if (tieneConsultaAcobrar)
                cargarPrecioConsulta();
        }

        private void cargarOSpaciente()
        {
            precioRecibo = PrecioACobrar.obraSocial;
            if (osPacientes == null)
            {
                //traemos desde la bd las obras sociales del paciente
                osPacientes = Pacientess.obtenerOSPaciente(miTurno.NroHCPaciente);
                if (osPacientes != null)
                {
                    cmbOSpaciente.DataSource = osPacientes;
                    cmbOSpaciente.DisplayMember = "NombreOS";
                    cmbOSpaciente.ValueMember = "idObraSocial";
                    cmbOSpaciente.Visible = true;
                    txtNroAfiliadoOS.Visible = true;
                }
                else
                {
                    MessageBox.Show("No se encontró Obra Social con convenio vigente para este paciente", "Error", MessageBoxButtons.OK);
                }

            }
        }

        private void cmbOSpaciente_SelectionChangeCommitted(object sender, EventArgs e)
        {
            //tomamos la OS que selecciono y le cargamos el nro de afiliado y buscamos el convenio de precios de dichaOS
            int idOS = int.Parse(cmbOSpaciente.SelectedValue.ToString());
            foreach (ObraSocialXPaciente item in osPacientes)
            {
                if (item.idObraSocial == idOS)
                {
                    txtNroAfiliadoOS.Text = item.nroAfiliado.ToString();

                    //buscamos la obra social y su convenio
                    GestorObraSocial gos = new GestorObraSocial();
                    osPacienteSeleccionada = gos.obtenerOSconConvenio(item.idObraSocial);

                    break;
                }
            }

            if (tieneConsultaAcobrar)
                cargarPrecioConsulta();
        }

        private void cargarPrecioConsulta()
        {
            float precioConsulta = 0;
            switch (precioRecibo)
            {
                case PrecioACobrar.particular:
                    precioConsulta = GestorEspecialidades.ObtenerPrecioListaEspecialidad(miTurno.IdEspecialidad);
                    precioMedico = GestorEspecialidades.ObtenerPrecioMedicoEspecialidad(miTurno.IdEspecialidad);
                    break;
                case PrecioACobrar.obraSocial:
                    foreach (DetalleConvenioOS item in osPacienteSeleccionada.miConvenioActual.DetalleConvenioOS)
                    {
                        if (item.idEspecialidad != null && miTurno.IdEspecialidad == item.idEspecialidad)
                        {
                            precioConsulta = item.precioAfiliado;
                            precioMedico = item.precioMedico;
                            break;
                        }
                    }
                    break;
                case PrecioACobrar.afiliado:
                    foreach (DetallePlanAfiliacion item in planAfPaciente.miPlanAfiliacion.DetallePlanAfiliacion)
                    {
                        if (item.idEspecialidad != null && item.idEspecialidad == miTurno.IdEspecialidad)
                        {
                            precioConsulta = item.precioAfiliado;
                            precioMedico = item.precioMedico;
                            break;
                        }
                    }
                    break;
            } //fin switch
            grdDetalleCobro.Rows[0].Cells["Precio"].Value = precioConsulta;
            subtotal += precioConsulta;
            txtSubtotal.Text = subtotal.ToString();

            calcularTotal();
        }


        private void grdDetalleCobro_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }

        private void chkHabilitarDescuento_CheckedChanged(object sender, EventArgs e)
        {
            if (chkHabilitarDescuento.Checked)
                txtDescuento.Enabled = true;
            else
                txtDescuento.Enabled = false;
        }

        private void chkHabilitarRecargo_CheckedChanged(object sender, EventArgs e)
        {
            if (chkHabilitarRecargo.Checked)
                txtRecargo.Enabled = true;
            else
                txtRecargo.Enabled = false;
        }

        private void rdbEspecialidad_CheckedChanged(object sender, EventArgs e)
        {
            if (rdbEspecialidad.Checked)
            {
                cmbEspecialidades.Enabled = true;
                cmbPracticas.Enabled = false;
            }

        }

        private void rdbPractica_CheckedChanged(object sender, EventArgs e)
        {
            if (rdbPractica.Checked)
            {
                cmbEspecialidades.Enabled = false;
                cmbPracticas.Enabled = true;
            }
        }

        private void btnCancelar_Click(object sender, EventArgs e)
        {
            //primero validar si se guardo o no el cobro
            this.Dispose();
        }

        private void calcularTotal()
        {
            total = subtotal + recargo - descuento;
            txtTotal.Text = total.ToString();
        }

        private void txtSubtotal_TextChanged(object sender, EventArgs e)
        {
            subtotal = float.Parse(txtSubtotal.Text);
            calcularTotal();
        }

        private void txtDescuento_TextChanged(object sender, EventArgs e)
        {
            if (txtDescuento.Enabled && (!string.IsNullOrEmpty(txtDescuento.Text)))
            {
                descuento = float.Parse(txtDescuento.Text);
                calcularTotal();
            }
        }

        private void txtRecargo_TextChanged(object sender, EventArgs e)
        {
            if (txtRecargo.Enabled && (!string.IsNullOrEmpty(txtRecargo.Text)))
            {
                recargo = float.Parse(txtRecargo.Text);
                calcularTotal();
            }
        }



        #region keyPress
        private void txtDescuento_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (Char.IsDigit(e.KeyChar))
            {
                e.Handled = false;
            }
            else if (Char.IsControl(e.KeyChar))
            {
                e.Handled = false;
            }
            else if (char.IsPunctuation(e.KeyChar))
            {
                e.Handled = false;
            }
            else
            {
                e.Handled = true;
            }
        }
        private void txtRecargo_KeyPress(object sender, KeyPressEventArgs e)
        {

            if (Char.IsDigit(e.KeyChar))
            {
                e.Handled = false;
            }
            else if (Char.IsControl(e.KeyChar))
            {
                e.Handled = false;
            }
            else if (char.IsPunctuation(e.KeyChar))
            {
                e.Handled = false;
            }
            else
            {
                e.Handled = true;
            }
        }
        #endregion

        private void btnAceptar_Click(object sender, EventArgs e)
        {
            //primero validamos
            if (validarDatos())
            {
                totalEnLetras = txtTotalLetras.Text;
                reciboNuevo = new Recibo();
                reciboNuevo.Fecha = DateTime.Now;
                reciboNuevo.NroHCpaciente = miTurno.NroHCPaciente;
                reciboNuevo.IdPersonaPaciente = (long)miTurno.IdPersona;
                reciboNuevo.Subtotal = subtotal;
                reciboNuevo.Total = total;
                reciboNuevo.TotalEnLetras = totalEnLetras;
                if (txtRecargo.Enabled && !string.IsNullOrEmpty(txtRecargo.Text))
                    reciboNuevo.Recargo = float.Parse(txtRecargo.Text);
                else
                    reciboNuevo.Recargo = 0;
                if (txtDescuento.Enabled && !string.IsNullOrEmpty(txtDescuento.Text))
                    reciboNuevo.Descuento = float.Parse(txtDescuento.Text);
                else
                    reciboNuevo.Descuento = 0;

                //cargamos los detalles del recibo
                reciboNuevo.MisDetallesRecibo = new List<DetalleRecibo>();
                DetalleRecibo dr = null;
                for (int i = 0; i < grdDetalleCobro.RowCount; i++)
                {
                    dr = new DetalleRecibo();
                    dr.Concepto = grdDetalleCobro.Rows[i].Cells["Concepto"].Value.ToString();
                    dr.Monto = float.Parse(grdDetalleCobro.Rows[i].Cells["Precio"].Value.ToString());
                    if (grdDetalleCobro.Rows[i].Cells["IdEspecialidad"].Value != null)
                        dr.IdEspecialidad = int.Parse(grdDetalleCobro.Rows[i].Cells["IdEspecialidad"].Value.ToString());
                    else
                        dr.IdEspecialidad = null;
                    if (grdDetalleCobro.Rows[i].Cells["IdPractica"].Value != null)
                        dr.IdPractica = int.Parse(grdDetalleCobro.Rows[i].Cells["IdPractica"].Value.ToString());
                    else
                        dr.IdPractica = null;
                    dr.IdCuotaAfiliado = null;

                    //agregamos a la lista del recibo
                    reciboNuevo.MisDetallesRecibo.Add(dr);
                    dr = null;
                }

                //ahora obtenemos el ultimo nro de recibo generado, y en caso de no haber, asignamos por defecto, 001-000001
                if (!GestorCobrosAtencionMedica.hayRecibo())
                {
                    reciboNuevo.NroSerie = 001;
                    reciboNuevo.NroRecibo = 000001;
                }
                else
                {
                    int nroSerieR;
                    long nroRec;
                    GestorCobrosAtencionMedica.obtenerUltimoRecibo(out nroSerieR, out nroRec);
                    reciboNuevo.NroRecibo = nroRec + 1;
                    reciboNuevo.NroSerie = nroSerieR;
                }

                //ahora guardamos el recibo en la bd y le cargamos al turno el nro de recibo cobrado
                if (tieneConsultaAcobrar)
                {
                    int idEstTurno = 0;
                    if (miTurno.IdEstadoTurno == 3) //asistido no cobrado
                        idEstTurno = 4;
                    else if (miTurno.IdEstadoTurno == 5) //atendido no cobrado
                        idEstTurno = 6;
                    bool res = GestorCobrosAtencionMedica.registrarRecibo(reciboNuevo, idTurno, idEstTurno, precioMedico);

                    if (res)
                    {
                        agregarCobroToCajaDiaria(reciboNuevo);
                        btnImprimir.Visible = true;
                        MessageBox.Show("Se registró correctamente el cobro de la atención médica", "Información", MessageBoxButtons.OK, MessageBoxIcon.Information);

                        formGestionTurno.actualizarEstadoTurno();
                    }
                    else
                    {
                        MessageBox.Show("No se ha podido registrar el cobro de la atención médica", "Información", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }

                }


            }
        }

        private void agregarCobroToCajaDiaria(Recibo reciboNuevo)
        {
            DetalleCajaDiaria detalle = new DetalleCajaDiaria();
            detalle.NroSerieRecibo = reciboNuevo.NroSerie;
            detalle.NroRecibo = reciboNuevo.NroRecibo;
            detalle.IdTipoMovimiento = 1;
            detalle.Monto = reciboNuevo.Total;
            detalle.Observaciones = "Cobro atención médica";
            if (tieneConsultaAcobrar)
                detalle.Observaciones += reciboNuevo.MisDetallesRecibo[0].Concepto;
            detalle.IdCaja = ((frmMdiContainer)this.MdiParent).MiCaja.IdCaja;
            
            //guardamos el detalle_CajaDiaria en la bd
            GestorCaja gc = new GestorCaja();
            bool res = gc.registrarDetalleEnCaja(detalle);
            if (res)
            {
                //buscamos el id del detalle
                detalle.IdDetalleCajaDiaria = gc.obtenerUltimoIDDetalleEnCaja(detalle.IdCaja);

                //agregamos el detalle a la caja
                ((frmMdiContainer)this.MdiParent).MiCaja.DetallesCajaDiaria.Add(detalle);
            }
        }

        private bool validarDatos()
        {
            bool res = true;
            string error = "";
            if (grdDetalleCobro.RowCount == 0)
            {
                res = false;
                error = "No hay conceptos para cobrar \n\r";
            }
            if (string.IsNullOrEmpty(txtTotalLetras.Text))
            {
                res = false;
                error += "El total en letras no ha sido ingresado";
            }

            if (!res)
                MessageBox.Show(error, "Advertencia", MessageBoxButtons.OK);
            return res;
        }

        private void btnImprimir_Click(object sender, EventArgs e)
        {
            if (reciboNuevo != null)
            {
                frmMostrarRecibo formRecibo = new frmMostrarRecibo();
                formRecibo.recibo = reciboNuevo;
                formRecibo.ShowDialog();
            }
            
        }

        private void btnAgregar_Click(object sender, EventArgs e)
        {

        }







    }
}
